<?php

namespace app\health\command;

use app\common\model\Area;
use app\health\model\HealthEvaluationClick;
use app\health\model\HealthGoodsAccess;
use app\health\model\HealthUser;
use app\health\model\HealthUserChannel;
use app\health\model\HealthUserIdCard;
use app\health\model\HealthUserSignIn;
use app\health\model\statistics\HealthStatistics;
use app\health\model\tracking\HealthTrackingHealth;
use app\health\model\tracking\HealthTrackingUserRemain;
use think\console\Command;
use think\console\Input;
use think\console\Output;

class StatisticsCommand extends Command
{
    protected function configure()
    {
        $this->setName('health:statistics')->setDescription('鑫互助小程序数据统计');
    }

    /**
     * 数据统计脚本
     * @param Input $input
     * @param Output $output
     * @return void
     */
    protected function execute(Input $input, Output $output)
    {
        $output->writeln("------数据统计开始:" . date('Y-m-d H:i:s') . "------");
//        $startDate   = '2023-06-27';
//        $endDate     = date('Y-m-d', strtotime('yesterday'));
//        $currentDate = strtotime($startDate);
//        while (date('Y-m-d', $currentDate) <= $endDate) {
//            $day = date('Y-m-d', $currentDate);
//            $this->statistics($day, $input, $output);
//            $currentDate = strtotime('+1 day', $currentDate);
//        }
        $day = date('Y-m-d', strtotime('yesterday'));
        $this->statistics($day, $input, $output);
        $output->writeln("------数据统计结束:" . date('Y-m-d H:i:s') . "------");

    }

    /**
     * 数据统计入库
     * @param $day
     * @param Input $input
     * @param Output $output
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    protected function statistics($day, Input $input, Output $output): void
    {
        $output->writeln("------统计{$day}数据------");
        //清理这个时间的数据
        HealthStatistics::whereTime('day', 'between', [$day . ' 00:00:00', $day . ' 23:59:59'])->delete();
        $userChannel = HealthUserChannel::whereTime('register_date', '<=', $day . ' 23:59:59')
            ->select();
        $data        = [];
        $area        = Area::where('pid', 0)->column('id', 'shortname');
        foreach ($userChannel as $item) {
            $provinceId = $area[$item['province']] ?? 0;
            $key        = md5($day . $provinceId . $item['pid']);
            if (isset($data[$key])) {
                if (date('Y-m-d', strtotime($item['register_date'])) === $day) {
                    $data[$key]['new_user'] += 1;
                }
                $data[$key]['user_id'][] = $item['user_id'];
            } else {
                $data[$key] = [
                    'day'           => $day,
                    'province'      => $item['province'],
                    'province_id'   => $provinceId,
                    'channel_id'    => $item['pid'],
                    'new_user'      => date('Y-m-d', strtotime($item['register_date'])) === $day ? 1 : 0,
                    'user_id'       => [$item['user_id']],
                    'health_click'  => 0,
                    'health_people' => 0,
                ];
            }
        }
        //查询活跃用户
        $userRemain = $this->activeUser($day);
        //查询签到用户
        $signInUser = HealthUserSignIn::whereTime('createtime', 'between', [$day . ' 00:00:00', $day . ' 23:59:59'])
            ->column('user_id');
        //获取已实名认证用户
        $authenticationUser = HealthUserIdCard::whereTime('created_at', 'between', [$day . ' 00:00:00', $day . ' 23:59:59'])
            ->column('user_id');
        //查询健康服务点击记录
        $healthClick = HealthTrackingHealth::whereTime('created_at', 'between', [$day . ' 00:00:00', $day . ' 23:59:59'])
            ->group('user_id')
            ->column('user_id,count(*) as total');
        //查询测评点击记录
        $evaluationClick = HealthEvaluationClick::whereTime('create_time', 'between', [$day . ' 00:00:00', $day . ' 23:59:59'])
            ->group('user_id')
            ->column('user_id,count(*) as total');
        $goodsClick      = HealthGoodsAccess::whereTime('created_at', 'between', [$day . ' 00:00:00', $day . ' 23:59:59'])
            ->group('user_id')
            ->column('user_id,count(*) as total');
        foreach ($data as $datum) {
            $userIds                       = $datum['user_id'];
            $currentHealthClick            = array_intersect_key($healthClick, array_flip($userIds));
            $currentEvaluationClick        = array_intersect_key($evaluationClick, array_flip($userIds));
            $currentGoodsClick             = array_intersect_key($goodsClick, array_flip($userIds));
            $datum['active_user']          = count(array_intersect($userIds, $userRemain['total']));
            $datum['active_user_previous'] = count(array_intersect($userIds, $userRemain['previous']));
            $datum['sign_in_user']         = count(array_intersect($userIds, $signInUser));
            $datum['authentication_user']  = count(array_intersect($userIds, $authenticationUser));
            $datum['health_click']         = array_sum($currentHealthClick);
            $datum['health_people']        = count($currentHealthClick);
            $datum['evaluation_click']     = array_sum($currentEvaluationClick);
            $datum['evaluation_people']    = count($currentEvaluationClick);
            $datum['goods_click']          = array_sum($currentGoodsClick);
            $datum['goods_people']         = count($currentGoodsClick);
            unset($datum['user_id']);
            HealthStatistics::create($datum);
        }
    }

    /**
     * 计算活跃用户数据
     * @param $day
     * @return array|array[]
     */
    protected function activeUser($day): array
    {
        $userRemain = HealthTrackingUserRemain::whereTime('created_at', 'between', [$day . ' 00:00:00', $day . ' 23:59:59'])
            ->column('user_id,day');
        $data       = [
            'total'    => [],
            'previous' => []
        ];
        foreach ($userRemain as $userId => $dayNumber) {
            $data['total'][] = $userId;
            if ($dayNumber > 1) {
                $data['previous'][] = $userId;
            }
        }
        return $data;
    }
}